package com.gupaoedu.chat.server.handler;

import com.sun.jndi.toolkit.url.Uri;
import io.netty.channel.*;
import io.netty.handler.codec.HeadersUtils;
import io.netty.handler.codec.http.*;
import org.apache.log4j.Logger;

import java.io.File;
import java.io.RandomAccessFile;
import java.net.URI;
import java.net.URL;

public class HttpHandler extends SimpleChannelInboundHandler<FullHttpRequest> {
	private static Logger LOG = Logger.getLogger(HttpHandler.class);
	
	//获取class路径
    URL baseURL;

    private File getResource(String fileName) throws Exception{
        System.out.println("getResource fileName:"+fileName);
        fileName="webRoot/"+fileName;
        URL url=HttpHandler.class.getClassLoader().getResource(fileName);
        System.out.println("getResource path:"+(url.getPath()));
        return new File(url.getPath());
    }

    @Override
    public void channelRead0(ChannelHandlerContext ctx, FullHttpRequest request) throws Exception {

        //进行获取对应的访问相对路径-->过滤到对应的静态资源
        String uri=request.getUri();
        String resource=uri.equals("/")?"chat.html":uri;
        try {
            //定位到对应的静态 文件
            RandomAccessFile randomAccessFile=new RandomAccessFile(getResource(resource),"r");
            //编制响应体  HttpResponse DefaultHttpResponse
            HttpResponse httpResponse=new DefaultHttpResponse(request.protocolVersion(),HttpResponseStatus.OK);
            //返回的类型 判断出对应的准确类型contextType:.css .js  jpg|png|gif
            String contextType="text/html;";
            //设置response.headers 的类型: 准确的contentType  和编码类型
            if(uri.endsWith(".js")){
                contextType="text/js;";
            }else if(uri.endsWith(".css")){
                contextType="text/css；";
            }else if(uri.toLowerCase().matches("(png|jpg|png)$")){
                contextType="image/"+uri.substring(uri.lastIndexOf("."))+";";
            }
            contextType=contextType+"charset=urf-8;";
            httpResponse.headers().set(HttpHeaders.Names.CONTENT_TYPE,contextType);
            //从headers中获取到是否长连接isKeepAlive
            boolean isKeepAlive=HttpHeaders.isKeepAlive(request);
            //如果是长连接:往消息头中设置 contentLength 和connection
            if(isKeepAlive){
                //设置对应的长度
                httpResponse.headers().set(HttpHeaders.Names.CONTENT_LENGTH,randomAccessFile.length());
                //设置保持长连接
                httpResponse.headers().set(HttpHeaders.Names.CONNECTION,HttpHeaders.Values.KEEP_ALIVE);
            }
            //将消息反馈 response 返回写入!
            ctx.writeAndFlush(httpResponse);
            //将缺省文件region 写出:文件通道 文件长度
            ctx.writeAndFlush(new DefaultFileRegion(randomAccessFile.getChannel(),0,randomAccessFile.length()));
            //将empty_last_content 写出到ctx 得到channelFuture
            ChannelFuture channelFuture=ctx.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT);
            //如果不是长连接 增加监听 ChannelFutureListener.Close
            if(!isKeepAlive){
                channelFuture.addListener(ChannelFutureListener.CLOSE);
            }
            //randomAccessFile 文件关闭!
            randomAccessFile.close();
        } catch (Exception e) {
            e.printStackTrace();
            //如果找不到文件 直接返回 或者 404
            HttpResponse httpResponse=new DefaultFullHttpResponse(request.protocolVersion(),HttpResponseStatus.NOT_FOUND);
            ctx.writeAndFlush(httpResponse);
            ctx.close();
            return;
        }

    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
            throws Exception {
        Channel channel=ctx.channel();
        System.out.println("channel remote address:"+channel.remoteAddress());
         cause.printStackTrace();
        //关闭通道
        ctx.close();
    }
}

